package wortubung.core;

import java.util.ArrayList;
import java.util.List;

import static wortubung.util.CommonUtils.*;

public class MEANING {
    private Item host;
    private POSInfo posInfo;
    private String meaning;
    private String meaningInCJK;
    private List<EXAMPLE> examples;

    /**
     * @param meaning  CJK explanations can follow a '#'.
     *                 This is only meaningful for a non-CJK capable environment.
     *                 For Japanese words and sentences, for instance, this is not
     *                 necessary since the displaying system must be CJK capable.
     */
    public MEANING(Item host, String meaning, POSInfo posInfo) {
    	this.host = host;
        this.posInfo = posInfo;

        int idx = meaning.indexOf("#");
        if (idx <= 0) {
        	this.meaning = meaning;
        	this.meaningInCJK = null;
        } else {
        	this.meaning = meaning.substring(0, idx).trim();
        	this.meaningInCJK = meaning.substring(idx+1).trim();
        	if (this.meaningInCJK.length() == 0)
        		this.meaningInCJK = null;
        }
    }

    public String getMeaning() { return meaning; }
    public String getMeaningInCJK() { return meaningInCJK; }
    public boolean hasCJK() { return meaningInCJK != null; }
    public List<EXAMPLE> getExamples() { return examples; }
    public int numExamples() { return length(examples); }
    public Item getHost() { return host; }
    public POS getPOS() { return posInfo.getPOS(); }
    public POSCategory getPOSCategory() { return getPOS().getCategory(); }
    public String getPOSDisplay(boolean full) { return (posInfo == null) ? null : posInfo.toDisplay(full); }
    public POSInfo getPOSInfo() { return posInfo; }
    public NounCategory getNounCategory() { return posInfo.getNounCategory(); }
    public boolean isReflexiveVerb() { return getPOS().isReflexiveVerb(); }
    public boolean isNoun() { return getPOS().isNoun(); }
    public boolean isVerb() { return getPOS().isVerb(); }
    public boolean isAdjective() { return getPOS() == POS.ADJ; }
    public boolean isAdverb() { return getPOS() == POS.ADV; }
    public boolean isExclamation() { return getPOS() == POS.EXCLAMATION; }
    public boolean isSmallWord() { return getPOS().isSmallWord(); }
    public boolean isFixedUsage() { return host instanceof FixedUsage; }

    public boolean matches(String regex) {
    	if (isEmpty(meaning))
    		return false;

    	String x;
    	if (host instanceof WORD)
    		x = meaning.replaceAll("~~", ((WORD)host).getAnglicizedWord());
    	else
    		x = meaning;
    	return x.matches(regex);
    }

    public String getMeaningFull() {
    	if (meaning == null)
    		return null;
    	if (host instanceof WORD)
    		return meaning.replaceAll("~~", ((WORD)host).getAnglicizedWord());
    	return meaning;
    }

    public String getMeaningDisplay(boolean isPOSFullName) {
    	String pos = getPOSDisplay(isPOSFullName);
    	if (pos != null)
    		pos = "/" + pos + "/";
    	else
    		pos = null;
    	if (isEmpty(meaning))
        	return pos;
    	else
    		return pos + ' ' + getMeaningFull();
    }

    public void addExample(EXAMPLE ex) {
        if (examples == null)
            examples = new ArrayList<EXAMPLE>();
        examples.add(ex);
    }

    public MEANING clone(POSInfo _posInfo) {
    	MEANING m = new MEANING(this.host, this.meaning, _posInfo);
    	m.examples = this.examples;
    	return m;
    }
}
